﻿#include "FastFind.au3"

$win = "디아블로 III"

HotKeySet(",", "Toggle")
HotKeySet(".", "Stop")
HotKeySet("/", "PrintPixelColor")
HotKeySet("'", "loot")

Global $gameDelay = 1.0

Const $pixelMenu = 0x2C6770
Const $pixelInTown = 0xCFCFD0
Const $pixelShop = 0xCE7B29
Const $pixelDeposit = 0xCE7B29

Const $heroPos = [485, 310]

;---------------------------------------------------------------------------------
Const $PI = 3.14159265359

Opt("PixelCoordMode", 0)
Opt("MouseCoordMode", 0)

Enum $statusNone = 0, $statusMenu, $statusInTown, $statusShop, $statusDeposit, $statusDungeon, $statusBattle, $statusLoot, $statusDone

Global $hWnd = WinActivate($win)
Global $macroSize[2] = [960, 600]
Global $winPos = WinGetPos($hWnd)

FFSetWnd($hWnd, False)

Global $pause = False
Global $loopCount = 0
Global $hStateTimer = 0

Global $state = $statusNone
Global $nextState = $statusNone

WinMove($hWnd, "", $winPos[0], $winPos[1], $macroSize[0], $macroSize[1])
changeState($statusMenu)

While True
   Sleep(100)

   If ($pause = True) Then
	  ContinueLoop
   EndIf

   If WinActive($hWnd) = 0 Then
	  Sleep(1000)
	  WinActivate($hWnd)
   EndIf

   FFSnapShot(200, 0, 760, 500)

   Local $pixel = PixelGetColor(447, 268)
   If $pixel = 0xA36503 Then
	  MouseClick("left", 478, 382)
	  Sleep(3000)
	  Reset()
   EndIf

   If $nextState <> $statusNone Then
	  checkStateChange()
	  ContinueLoop
   EndIf

   Switch $state
   Case $statusMenu
	  statusMenu()
   Case $statusInTown
	  statusInTown()
   Case $statusShop
	  statusShop()
   Case $statusDeposit
	  statusDeposit()
   Case $statusDungeon
	  statusDungeon()
   Case $statusBattle
	  statusBattle()
   Case $statusLoot
	  statusLoot()
   Case $statusDone
	  statusDone()
   EndSwitch
WEnd

Func changeState($newState)
   $nextState = $newState
   $hStateTimer = TimerInit()
EndFunc

Func checkStateChange()
   If $state <> $statusMenu And $state <> $statusDone And TimerDiff($hStateTimer) > (10000 * $gameDelay) Then
	  changeState($statusDone)
   EndIf

   Switch $nextState
   Case $statusMenu
	  Local $pixel = PixelGetColor(145, 225)
	  If $pixel <> $pixelMenu Then
		 ToolTip("statusMenu : " & $loopCount & ", pixel : " & $pixel, $winPos[0] + 100, $winPos[1] + 5)
		 Return
	  EndIf

	  $loopCount += 1
	  ToolTip("statusMenu : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusInTown
	  Local $pixel = PixelGetColor(935, 39)
	  If $pixel <> $pixelInTown Then
		 ToolTip("statusInTown : " & $loopCount & ", pixel : " & $pixel, $winPos[0] + 100, $winPos[1] + 5)
		 Return
	  EndIf

	  ToolTip("statusInTown : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusShop
	  Local $pixel = PixelGetColor(800, 71)
	  If $pixel <> $pixelShop Then
		 ToolTip("statusShop : " & $loopCount & ", pixel : " & $pixel, $winPos[0] + 100, $winPos[1] + 5)
		 Return
	  EndIf

	  ToolTip("statusInShop : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusDeposit
	  Local $pixel = PixelGetColor(800, 71)
	  If $pixel <> $pixelDeposit Then
		 ToolTip("statusDeposit : " & $loopCount & ", pixel : " & $pixel, $winPos[0] + 100, $winPos[1] + 5)
		 Return
	  EndIf

	  ToolTip("statusInDeposit : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusDungeon
	  ToolTip("statusDungeon : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusBattle
	  ToolTip("statusBattle : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusLoot
	  ToolTip("statusLoot : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   Case $statusDone
	  Local $pixel = PixelGetColor(790, 70)
	  If $pixel <> 0xB00639 Then
		 Send("{ESC}")
		 Sleep(500 * $gameDelay)
		 Return
	  EndIf

	  ToolTip("statusDone : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)

   EndSwitch

   $state = $nextState
   $nextState = $statusNone
   $hStateTimer = TimerInit()
EndFunc

Func statusMenu()
   Sleep(500 * $gameDelay)
   MouseClick("left", 183, 317)

   changeState($statusInTown)
EndFunc

Func statusInTown()
   Sleep(500 * $gameDelay)
   Send("{SHIFTDOWN}")
   MouseClick("Left", 420, 300)
   Send("{SHIFTUP}")
   Sleep(1000 * $gameDelay)
   Send("1")
   Sleep(500 * $gameDelay)

   Static Local $shopCount = 1
   If $shopCount = 20 Then
	  $shopCount = 1

	  MouseClick("left", 523, 69)
	  Sleep(1000)

	  changeState($statusShop)
   Else
	  $shopCount += 1

	  MouseClick("left", 17, 41)
	  Sleep(3000)

	  changeState($statusDungeon)
   EndIf

EndFunc

Func statusShop()
   MouseClick("Left", 291, 373)
   Sleep(300 * $gameDelay)
   MouseClick("Left", 154, 362)
   Sleep(300 * $gameDelay)
   MouseClick("Left", 287, 297)
   Sleep(300 * $gameDelay)
   MouseClick("Left", 150, 194)
   Sleep(300 * $gameDelay)

   Local $pos[2] = [678, 353]
   For $i = 0 To 5 Step 1
	  For $j = 0 To 9 Step 1
		 MouseClick("left", $pos[0] + $j * 28, $pos[1] + $i * 28, 1, 0)
		 Sleep(300 * $gameDelay)
		 Local $pixel = PixelGetColor(516, 131)
		 If $pixel = 0x130704 Then
			MouseClick("left", 540, 235)
			Sleep(300 * $gameDelay)
			MouseClick("Left", 150, 194)
			Sleep(300 * $gameDelay)
		 EndIf
	  Next
   Next

   Send("{ESC}")
   Sleep(500 * $gameDelay)

   MouseClick("Left", 25, 207)
   Sleep(1000)

   changeState($statusDeposit)
EndFunc

Func statusDeposit()
   For $slotNum = 0 To 3 Step 1
	  Local $tabPos[2] = [295, 160]
	  MouseClick("left", $tabPos[0], $tabPos[1] + $slotNum * 70)
	  Sleep(500 * $gameDelay)

	  Local $pixel = PixelGetColor(248, 421)
	  If $pixel = 0x100B08 Then
		 ExitLoop
	  EndIf
   Next

   Local $pos[2] = [678, 353]
   For $i = 0 To 5 Step 1
	  For $j = 0 To 9 Step 1
		 If ($i = 0 Or $i = 1) And $j = 0 Then
			ContinueLoop
		 EndIf

		 MouseClick("right", $pos[0] + $j * 28, $pos[1] + $i * 28, 1, 0)
		 Sleep(200 * $gameDelay)
	  Next
   Next

   Send("{ESC}")
   Sleep(500 * $gameDelay)

   MouseClick("Left", 292, 338)
   Sleep(1000)

   changeState($statusDungeon)
EndFunc

Func statusDungeon()
   Static Local $navigateStep = 0
   Static Local $hNavigateTimer = 0

   Switch $navigateStep
   Case 0
	  Local $pixel = PixelGetColor(901, 40)
	  If $pixel = 0xDFE0E0 Then
		 $navigateStep = 1
		 $hNavigateTimer = TimerInit()
	  EndIf
   Case 1
	  Sleep(500 * $gameDelay)
	  Local $wellPos = PixelSearch(923, 419, 949, 447, 0xDCA81E, 20)
	  If Not @error Then
		 MouseClick("left", 909, 404)
		 Sleep(2000)
		 MouseClick("left", 72, 50)
		 Sleep(1000)
	  Else
		 MouseClick("left", 311, 152)
		 Sleep(1000)
	  EndIf
	  $navigateStep = 2
   Case 2
	  Local $pixel = PixelGetColor(844, 39)
	  If $pixel = 0xBFC0C0 Then
		 $navigateStep = 3
		 $hNavigateTimer = TimerInit()
	  EndIf
#cs
   Case 3
	  moveAngle(140)
	  Send("1")
	  If (TimerDiff($hNavigateTimer) > 2000) Then
		 $navigateStep = 4
		 $hNavigateTimer = TimerInit()
	  EndIf
   Case 4
	  moveAngle(160)
	  If (TimerDiff($hNavigateTimer) > 1000) Then
		 $navigateStep = 5
		 $hNavigateTimer = TimerInit()
	  EndIf
   Case 5
	  moveAngle(340)
	  If (TimerDiff($hNavigateTimer) > 2500) Then
		 $navigateStep = 6
		 $hNavigateTimer = TimerInit()
	  EndIf
   Case 6
	  moveAngle(270)
	  If (TimerDiff($hNavigateTimer) > 2000) Then
		 $navigateStep = 7
		 $hNavigateTimer = TimerInit()
	  EndIf
#ce
   Case 3
	  moveAngle(140)
	  If TimerDiff($hStateTimer) > 500 Then
		 MouseClick("right", 537, 250)
		 $navigateStep = 7
		 $hNavigateTimer = TimerInit()
	  EndIf

   Case 7
	  If TimerDiff($hStateTimer) > 500 Then
		 $hStateTimer = TimerInit()

		 If (findEnemy() = True) Then
			Send("1")
			Sleep(500 * $gameDelay)
			Send("2")
			Sleep(500 * $gameDelay)
			Send("3")
			Sleep(500 * $gameDelay)
			Send("4")
			changeState($statusBattle)
			Return
		 EndIf

		 If (loot() = True) Then
			$navigateStep = 0
			changeState($statusLoot)
			Return
		 EndIf
	  EndIf

	  If (TimerDiff($hNavigateTimer) > 20000) Then
		 $navigateStep = 0
		 changeState($statusDone)
	  EndIf
   EndSwitch
EndFunc

Func moveAngle($angDeg)
   Local $angRad = $angDeg / 180 * $PI
   Local $x = 70 * Cos($angRad)
   Local $y = 70 * Sin($angRad)
   MouseMove($heroPos[0] + $x, $heroPos[1] + $y, 0)
   Send("w")
EndFunc

Func statusBattle()
   If (findEnemy() = True) Then
	  $hStateTimer = TimerInit()

	  Local $mousePos = MouseGetPos()
	  Local $direction[2] = [$heroPos[0] - $mousePos[0], $heroPos[1] - $mousePos[1]]

	  Local $x2 = $direction[0] * $direction[0]
	  Local $y2 = $direction[1] * $direction[1]

	  Local $dist = Sqrt($x2 + $y2)

	  If $dist < 50 Then
		 MouseMove($heroPos[0] + 30 * $direction[0] / $dist, $heroPos[1] + 30 * $direction[1] / $dist , 0)
		 Send("w")
		 Sleep(500)
	  EndIf
   EndIf

   If TimerDiff($hStateTimer) > 2000 Then
	  changeState($statusDungeon)
	  Return
   EndIf

   MouseClick("right")
EndFunc

Func statusLoot()
   MouseMove(250, 150, 0)

   Static Local $notLootCount = 0
   If loot() = True Then
	  $notLootCount = 0
   EndIf

   If $notLootCount > 5 Then
	  $notLootCount = 0
	  changeState($statusDone)
	  Return
   EndIf

   If TimerDiff($hStateTimer) > 5000 Then
	  $notLootCount = 0
	  changeState($statusDone)
	  Return
   EndIf
EndFunc

Func findEnemy()
   FFResetExcludedAreas( )
   FFAddExcludedArea(390, 65, 565, 80)

   FFResetColors()
   Local $color = 0xC00000
   While $color < 0xFF0000
	  FFAddColor($color)
	  $color += 0x010000
   WEnd

   Local $pos = FFNearestSpot(1, 1, $heroPos[0], $heroPos[1], -1, 0, False)
   If Not @error Then
	  ToolTip("FindEnemy", $winPos[0] + 100, $winPos[1] + 5)
	  MouseMove($pos[0], $pos[1] + 50)
	  Return True
   EndIf

   ToolTip("NotFindEnemy", $winPos[0] + 100, $winPos[1] + 5)
   Return False
EndFunc

Func loot()
   FFResetExcludedAreas( )
   FFResetColors()
   FFAddColor(0x1C1008)
   FFAddColor(0x231008)
   FFAddColor(0x130A03)
   FFAddColor(0x291408)

   Local $pos = FFNearestSpot(1, 1, $heroPos[0], $heroPos[1], -1, 0, False)
   If Not @error Then
	  ToolTip("Loot", $winPos[0] + 100, $winPos[1] + 5)
	  MouseClick("left", $pos[0], $pos[1], 1, 0)

	  Local $x2 = ($heroPos[0] - $pos[0]) * ($heroPos[0] - $pos[0])
	  Local $y2 = ($heroPos[1] - $pos[1]) * ($heroPos[1] - $pos[1])

	  Local $dist = Sqrt($x2 + $y2)
	  Sleep((300 + (500 * $dist / 100))* $gameDelay )
	  Return True
   EndIf

   ToolTip("NotLoot", $winPos[0] + 100, $winPos[1] + 5)
   Return False
EndFunc

Func statusDone()
   MouseClick("left", 172, 298)
   Sleep(1000)

   MouseMove(100, 100)
   Sleep(5000)

   changeState($statusMenu)
EndFunc

Func Toggle()
   If $pause = True Then
	  $pause = False
	  ToolTip("Resume", $winPos[0] + 100, $winPos[1] + 5)
   Else
	  $pause = True
	  ToolTip("Pause : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)
   EndIf
EndFunc

Func Stop()
   ToolTip("Stop : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)
   Sleep(2000)
   Exit
EndFunc

Func Reset()
   ToolTip("Reset : " & $loopCount, $winPos[0] + 100, $winPos[1] + 5)
   Global $state = $statusNone
   Global $nextState = $statusMenu
   Sleep(2000)
EndFunc

Func PrintPixelColor()
   Local $pos = MouseGetPos()
   Local $color = PixelGetColor ($pos[0] , $pos[1])
   ToolTip($pos[0]&","&$pos[1]&":"&$color, $winPos[0] + 100, $winPos[1] + 5)
   Sleep(100000)
   Exit
EndFunc